package validata

import (
	"github.com/gin-gonic/gin"
	"go-member/model"
	"go-member/tool"
	"regexp"
	"strconv"
	"strings"
	"unicode/utf8"
)

// Check
// @Description: 表单验证
// @param c
// @param rule
// @return any
func Check(c *gin.Context, rule map[string]string) any {
	c.Request.ParseMultipartForm(128) //保存表单缓存的内存大小128M
	query := c.Request.Form
	var queryMap = make(map[string]string, len(query))
	if c.Request.Method == "POST" {
		for k := range query {
			queryMap[k] = c.PostForm(k)
		}
	} else {
		for k := range query {
			queryMap[k] = c.Query(k)
		}
	}
	for k := range rule {
		first := k[:strings.Index(k, ".")]
		after := k[strings.Index(k, ".")+1:]
		val := queryMap[first]
		ok := false
		if strings.Index(after, "|") == -1 {
			ok = checkMap(after, val, "")
		} else {
			firstStr := after[:strings.Index(after, "|")]
			lastStr := after[strings.Index(after, "|")+1:]
			ok = checkMap(firstStr, val, lastStr)
		}
		if !ok {
			return rule[k]
		}
	}
	return nil
}

// checkMap
// @Description: 验证规则
// 已有常规规则:(required|uint|phone|email|realm_name|min|max|between|)
// 业务规则:(existsCategory|existsUserName|existsNotUserName|existsUser|existsDelUser)
// @param key
// @param val
// @return bool
func checkMap(key, val, lastStr string) bool {
	switch key {
	// 校验为空
	case "required":
		if val == "" {
			return false
		}
		return true
	//校验是否为unit
	case "uint":
		if val == "" {
			return true
		}
		val, err := strconv.Atoi(val)
		if err != nil {
			return false
		}
		if tool.GetType(val) != "int" || val < 1 {
			return false
		}
		return true
	// 校验最小长度
	case "min_len":
		if val == "" {
			return true
		}
		lastInt, err := strconv.Atoi(lastStr)
		if err != nil {
			return false
		}
		return utf8.RuneCountInString(val) >= lastInt
	// 校验最大长度
	case "max_len":
		if val == "" {
			return true
		}
		lastInt, err := strconv.Atoi(lastStr)
		if err != nil {
			return false
		}
		return utf8.RuneCountInString(val) <= lastInt
	// 校验是否是手机号
	case "phone":
		if val == "" {
			return true
		}
		ok, _ := regexp.MatchString(`^(1[2|3|4|5|6|7|8|9][0-9]\d{8})$`, val)
		if !ok {
			return false
		}
		return true
	// 校验是否为邮箱
	case "email":
		if val == "" {
			return true
		}
		ok, _ := regexp.MatchString(`^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(.[a-zA-Z0-9_-]+)+$`, val)
		if !ok {
			return false
		}
		return true
	// 校验是否为域名
	case "realm_name":
		if val == "" {
			return true
		}
		ok, _ := regexp.MatchString(`^((http://)|(https://))?([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?.)+[a-zA-Z]{2,6}(/)`, val)
		if !ok {
			return false
		}
		return true
	// 最小值 规则  field.min|1
	case "min":
		if val == "" {
			return true
		}
		afterStr := lastStr[strings.Index(lastStr, "|")+1:]
		lastInt, err1 := strconv.Atoi(afterStr)
		valInt, err2 := strconv.Atoi(val)
		if err1 != nil || err2 != nil {
			return false
		}
		if lastInt > valInt {
			return false
		}
		return true
	// 最大值 规则  field.max|10
	case "max":
		if val == "" {
			return true
		}
		afterStr := lastStr[strings.Index(lastStr, "|")+1:]
		lastInt, err1 := strconv.Atoi(afterStr)
		valInt, err2 := strconv.Atoi(val)
		if err1 != nil || err2 != nil {
			return false
		}
		if lastInt < valInt {
			return false
		}
		return true
	// 检测是否在某个范围之间规则  field.between|(1,2)
	case "between":
		if val == "" {
			return true
		}
		temFirst := lastStr[:strings.Index(lastStr, ",")]
		firstStr := temFirst[strings.Index(temFirst, "(")+1:]
		temAfter := lastStr[strings.Index(lastStr, ",")+1:]
		afterStr := temAfter[:strings.Index(temAfter, ")")]
		return tool.BetweenString(firstStr, afterStr, val)
	// 是否存在分类
	case "existsCategory":
		if val == "" {
			return true
		}
		return model.ExistsCategory(val)
	// 用户姓名是否存在
	case "existsUserName":
		if val == "" {
			return true
		}
		return model.ExistsUserName(val)
	// 用户姓名是否不存在
	case "existsNotUserName":
		if val == "" {
			return true
		}
		return !model.ExistsUserName(val)
	// 用户是否存在
	case "existsUser":
		if val == "" {
			return true
		}
		return model.ExistsUser(val)
	case "existsDelUser":
		if val == "" {
			return true
		}
		return model.ExistsDelUser(val)
	default:
		return true
	}

}
